package com.dragon.logical.service.contract.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.model.ResultCode;
import com.dragon.common.model.exception.CustomException;
import com.dragon.logical.service.contract.IEquipmentService;
import com.dragon.repository.entity.*;
import com.dragon.repository.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 设备 服务实现类
 * </p>
 *
 * @author sy
 * @since 2023-11-29
 */
@Service
public class EquipmentServiceImpl extends ServiceImpl<EquipmentMapper, Equipment> implements IEquipmentService {

    @Autowired
    EquipmentMapper equipmentMapper;
    @Autowired
    ProduceProductsMapper produceProductsMapper;
    @Autowired
    ProduceSchedulingMapper produceSchedulingMapper;
    @Autowired
    ProduceMapper produceMapper;
    @Autowired
    SchedulingSonMapper schedulingSonMapper;
    @Autowired
    SchedulingSonSonMapper sonSonMapper;
    @Autowired
    RejectedMapper rejectedMapper;
    @Autowired
    RejectedProductMapper rejectedProductMapper;

    @Override
    public List<Equipment> equipmentList(Integer type) {
        List<Equipment> equipments= equipmentMapper.selectListBy(type);
        equipments.forEach(equipment -> {
            List<Object> objectList = new ArrayList<>();
            if (equipment.getType() == 1){
                if (equipment.getSchedulingId() != null){
                    List<SchedulingSon> schedulingSonList = schedulingSonMapper.getListBySchedulingId(equipment.getSchedulingId(),null, equipment.getId());
                    schedulingSonList.forEach(schedulingSon -> {
                        objectList.add(schedulingSon);
                    });
                } else {
                    Integer schedulingId = equipmentMapper.getSchedulingIdByEquipmentId(equipment.getId());
                    equipment.setSchedulingId(schedulingId);
                }
                List<SchedulingSonSon> schedulingSonSons = sonSonMapper.selectList(new QueryWrapper<SchedulingSonSon>()
                        .lambda()
                        .eq(SchedulingSonSon::getEquipmentId, equipment.getId()));
                if (schedulingSonSons.size() != 0){
                    schedulingSonSons.forEach(schedulingSonSon -> {
                        objectList.add(schedulingSonSon);
                    });
                }
            }
            equipment.setSonList(objectList);
        });
        return equipments;
    }

    @Override
    public void equipmentAdd(Equipment equipment) {
        Equipment equipment1 = equipmentMapper.selectOne(new QueryWrapper<Equipment>().lambda().eq(Equipment::getEquipmentCode, equipment.getEquipmentCode()));
        if (equipment1 != null){
            throw new CustomException(ResultCode.EQUIPMENT_CODE_IS_REPEAT);
        }
        equipment.setCreateTime(DateUtil.date());
        equipmentMapper.insert(equipment);
    }

    @Override
    public void equipmentUpdate(Equipment equipment) {
        if (equipmentMapper.selectById(equipment.getId()).getType() == 1){
            throw new CustomException(ResultCode.EQUIPMENT_IS_WORK);
        }
        equipment.setUpdateTime(DateUtil.date());
        equipmentMapper.updateById(equipment);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void enterData(Equipment equipment){
        //获取 排产信息
        ProduceScheduling produceScheduling = produceSchedulingMapper.selectById(equipment.getSchedulingId());
        //获取 排产子表
        List<SchedulingSon> sonList = schedulingSonMapper.getListBySchedulingId(produceScheduling.getId(),null, null);
        //produceScheduling.setSchedulingSonList(sonList);
        //获取生产单产品
        sonList.forEach(schedulingSon -> {
            //判断 排产的产品是否是拆解键
            if (schedulingSon.getIsDismantle() == 1){
                //根据子表id+设备id 查拆解表数据
                QueryWrapper<SchedulingSonSon> wrapper1 = new QueryWrapper<>();
                wrapper1.lambda()
                        .eq(SchedulingSonSon::getSchedulingSonId, schedulingSon.getId())
                        .eq(SchedulingSonSon::getEquipmentId, equipment.getId())
                        .eq(SchedulingSonSon::getType,1);
                List<SchedulingSonSon> schedulingSonSons = sonSonMapper.selectList(wrapper1);
                schedulingSonSons.forEach(schedulingSonSon -> {
                    schedulingSonSon.setType(2);
                    schedulingSonSon.setUpdateTime(DateUtil.date());
                    sonSonMapper.updateById(schedulingSonSon);
                });
                wrapper1.clear();
                wrapper1.lambda()
                        .eq(SchedulingSonSon::getSchedulingSonId, schedulingSon.getId())
                        .ne(SchedulingSonSon::getType, 2);
                List<SchedulingSonSon> schedulingSonSons1 = sonSonMapper.selectList(wrapper1);
                if (schedulingSonSons1.size() == 0){
                    schedulingSon.setType(2);
                    schedulingSon.setUpdateTime(DateUtil.date());
                    schedulingSonMapper.updateById(schedulingSon);
                    //修改生产产品子表信息
                    QueryWrapper<ProduceProducts> wrapper = new QueryWrapper<>();
                    wrapper.lambda().eq(ProduceProducts::getProduceId, schedulingSon.getProduceId())
                            .eq(ProduceProducts::getQuotesProductId, schedulingSon.getProductId());
                    ProduceProducts produceProducts = produceProductsMapper.selectOne(wrapper);
                    produceProducts.setProduceNum(produceProducts.getProduceNum() + schedulingSon.getSchedulingNum());
                    if (produceProducts.getNum() <= produceProducts.getProduceNum()) {
                        produceProducts.setProduceStatus(2);
                    } else {
                        produceProducts.setProduceStatus(1);
                    }
                    produceProductsMapper.updateById(produceProducts);
                }
            } else {
                //判断子表的设备id 是否等于 录入数据的设备id
                if (schedulingSon.getEquipmentId().equals(equipment.getId())) {
                    //修改生产产品子表信息
                    QueryWrapper<ProduceProducts> wrapper = new QueryWrapper<>();
                    wrapper.lambda().eq(ProduceProducts::getProduceId, schedulingSon.getProduceId())
                            .eq(ProduceProducts::getQuotesProductId, schedulingSon.getProductId());
                    ProduceProducts produceProducts = produceProductsMapper.selectOne(wrapper);
                    produceProducts.setProduceNum(produceProducts.getProduceNum() + schedulingSon.getSchedulingNum());
                    if (produceProducts.getNum() <= produceProducts.getProduceNum()) {
                        produceProducts.setProduceStatus(2);
                    } else {
                        produceProducts.setProduceStatus(1);
                    }
                    produceProductsMapper.updateById(produceProducts);
                    //修改子表
                    schedulingSon.setType(2);
                    schedulingSon.setUpdateTime(DateUtil.date());
                    schedulingSonMapper.updateById(schedulingSon);
                    //判断生产单是否 从退货来
                    Produce produce = produceMapper.selectById(schedulingSon.getProduceId());
                    if (produce.getSource() == 1) {
                        //修改 退货产品中的 已处理数量
                        Rejected rejected = rejectedMapper.selectById(produce.getRejectedId());
                        QueryWrapper<RejectedProduct> wrapper1 = new QueryWrapper<>();
                        wrapper1.lambda().eq(RejectedProduct::getRejectedId, rejected.getId())
                                .eq(RejectedProduct::getProductId, schedulingSon.getProductId());
                        RejectedProduct rejectedProduct = rejectedProductMapper.selectOne(wrapper1);
                        int handleNum = rejectedProduct.getHandleNum() + schedulingSon.getSchedulingNum();
                        rejectedProduct.setHandleNum(handleNum);
                        rejectedProduct.setUpdateTime(DateUtil.date());
                        rejectedProductMapper.updateById(rejectedProduct);
                    }
                }
            }
        });
        List<SchedulingSon> sonList1 = schedulingSonMapper.selectList(new QueryWrapper<SchedulingSon>()
                .lambda()
                .eq(SchedulingSon::getSchedulingId, produceScheduling.getId())
                .eq(SchedulingSon::getType,2));
        if (sonList1.size() == 0){
            produceScheduling.setType(2);
            produceScheduling.setEndTime(DateUtil.date());
            produceSchedulingMapper.updateById(produceScheduling);
        }
        //修改设备状态
        equipment.setType(0);
        equipment.setUpdateTime(DateUtil.date());
        equipment.setEstimateFinishTime( DateUtil.parse("2000-01-01 00:00:00") );
        equipmentMapper.updateById(equipment);
        //判断生产单下的子表是否 全部生产/排产完成
        List<Integer> ids = Stream.of(produceScheduling.getProduceId().split(",")).map(Integer::valueOf).collect(Collectors.toList());
        ids.forEach(produceId->{
            //全部完成则修改主表信息
            updateProduceType(produceId);
        });
    }

    @Override
    public void updateProduceType(Integer produceId){
        Produce produce = produceMapper.selectById(produceId);
        //查看当前生产单下的所有产品
        QueryWrapper<ProduceProducts> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(ProduceProducts::getProduceId,produceId);
        List<ProduceProducts> totalProducts = produceProductsMapper.selectList(wrapper);
        //查看生产单下的产品是否完成
        wrapper.clear();
        wrapper.lambda().eq(ProduceProducts::getProduceId,produceId)
                .eq(ProduceProducts::getProduceStatus,2);
        List<ProduceProducts> produceProducts1 = produceProductsMapper.selectList(wrapper);
        //查看 生产单下 产品排产是否完成
        wrapper.clear();
        wrapper.lambda().eq(ProduceProducts::getProduceId,produceId)
                .ne(ProduceProducts::getSchedulingStatus,2);
        List<ProduceProducts> produceProducts2 = produceProductsMapper.selectList(wrapper);
        if(produceProducts1.size() != 0){
            if (produceProducts1.size() == totalProducts.size()){
                produce.setType(2);
                produce.setFinishedStatus(2);
                produce.setUpdateTime(DateUtil.date());
            }
            produce.setFinishedStatus(1);
        }
        if (produceProducts2.size() ==0 ) {
            produce.setSchedulingStatus(2);
        }
        produceMapper.updateById(produce);

        //退货完成状态判断
        if (produce.getSource() == 1){
            Rejected rejected = rejectedMapper.selectById(produce.getRejectedId());
            List<RejectedProduct> rejectedProducts = rejectedProductMapper.selectProductList(rejected.getId(), produceId);
            AtomicReference<Boolean> flag = new AtomicReference<>(true);
            rejectedProducts.forEach(rejectedProduct -> {
                if (!rejectedProduct.getRecededNum().equals(rejectedProduct.getHandleNum())){
                    flag.set(false);
                }
            });
            if (flag.get() == true){
                rejected.setRejectedState(1);
                rejected.setUpdateTime(DateUtil.date());
                rejectedMapper.updateById(rejected);
            }
        }
    }
}
